var express = require('express');
var router = express.Router();
var co = require('co');
var coRequest = require('co-request');
var request = require('request');
var moment = require('moment');
var _ = require('lodash');
var dao = require('../dao');
var fs = require('fs');

var idGen = require('../lib/idGen');
var LicenseCenter = require('../lib/LicenseCenter');
var commonUtils = require('../lib/commonUtils');
var httpResult = require('../lib/httpResult');

var XLSX = require('xlsx');
var node_xlsx = require('node-xlsx');

var multer = require('multer');
var storage = multer.memoryStorage();
var upload = multer({
    storage: storage,
    limits: {
        fileSize: 10485760,
        files: 1
    }
});

/**
 * 将 Array 转换成一个 Object, 以 keyName 的值为key
 * @param arr
 * @param keyName
 */
function indexByKey(arr, keyName) {
    var result = {};

    if (!arr || arr.length === 0) {
        return result;
    }

    for (var i = 0; i < arr.length; i++) {
        var key = arr[i][keyName];
        result[key] = arr[i];
    }

    return result;
}

function requestProxy(url, req, res) {
    co(function*() {
        var response = yield coRequest.get(url);

        if (response.statusCode === 200) {
            var body = JSON.parse(response.body);
            if (body.code === 0) {
                res.json(httpResult.succ(body.data));
            } else {
                res.json(httpResult.err_logic(body.msg));
            }
        } else {
            res.json(httpResult.err_logic(response.body));
        }
    });
}

/* show admin page */
router.get('/', function (req, res, next) {
    res.render('admin');
});

var buttonsFilePath = './buttons.json';
router.get('/buttons/create', function (req, res, next) {

    var validToken = req.query.token;


    if (validToken === 'admin') {
        co(function*(){
            var accessToken = yield LicenseCenter.access_token();

            var createUrl = `https://api.weixin.qq.com/cgi-bin/menu/create?access_token=${accessToken}`;

            var response = yield coRequest({
                url: createUrl,
                method: 'POST',
                body: JSON.parse(fs.readFileSync(buttonsFilePath)),
                json: true
            });

            if (response.statusCode == 200) {
                console.log(response.body);
                var body = response.body;
                if(body.errcode === 0){
                    res.json(body);
                }else{
                    res.json(body);
                }
            }
        }).catch(function (err) {
            console.error(err.stack);
            res.json(err);
        })
    } else {
        res.json('无权限');
    }
});

router.get('/balance', function (req, res) {
    var mobile = req.query.mobile;
    var queryType = req.query.queryType;

    var url = 'http://service.lvyou189.cn:9001/balance';
    var params = {
        mobile: mobile,
        queryType: +queryType
    };
    url = commonUtils.buildUrl(url, params);

    requestProxy(url, req, res);
});

router.get('/flowset', function (req, res) {
    var mobile = req.query.mobile;
    var month = req.query.month;

    var url = 'http://service.lvyou189.cn:9001/flowset';
    var params = {
        mobile: mobile,
        month: month
    };
    url = commonUtils.buildUrl(url, params);

    requestProxy(url, req, res);
});

router.get('/payment', function (req, res) {
    var mobile = req.query.mobile;
    var month = req.query.month;

    var url = 'http://service.lvyou189.cn:9001/chargeInfo';
    var params = {
        mobile: mobile,
        month: month
    };
    url = commonUtils.buildUrl(url, params);

    requestProxy(url, req, res);
});

router.post('/flowset/batch', upload.single('queryMobiles'), function (req, res) {
    var file = req.file;

    var result = xlsxParser(file, parseMobiles);

    if (result.code !== 0) {
        res.json(httpResult.err_logic(result.msg));
        return;
    }

    co(function*() {
        var mobiles = result.data.mobiles.toString();
        var response = yield coRequest.post({
            url: 'http://service.lvyou189.cn:9001/flowset',
            form: {
                mobiles: mobiles,
                month: moment().format('YYYYMM')
            }
        });

        if (response.statusCode === 200) {
            var body = JSON.parse(response.body);
            if (body.code === 0) {
                var resultData = buildBatchResult(body.data);

                res.attachment('套餐查询结果.xlsx');
                res.send(resultData);
            } else {
                res.json(httpResult.err_logic(response.body));
            }
        } else {
            res.json(httpResult.err_logic(response.body));
        }
    });
});

router.post('/chargeInfo/batch', upload.single('queryMobiles'), function (req, res) {
    var file = req.file;
    var year = +req.body.year;
    var month = +req.body.month;

    var result = xlsxParser(file, parseMobiles);

    if (result.code !== 0) {
        res.json(httpResult.err_logic(result.msg));
        return;
    }

    co(function *() {
        var mobiles = result.data.mobiles.toString();
        var now = moment();
        // now.month(now.month() - 1).format('YYYYMM'),
        // now.month(now.month() - 1).format('YYYYMM')
        var queryMonth = [
            now.year(year).month(month - 1).format('YYYYMM')
        ];

        var promises = _.map(queryMonth, function (item) {

            return new Promise(function (resolve, reject) {

                request.post({
                    url: 'http://service.lvyou189.cn:9001/chargeInfo',
                    form: {
                        mobiles: mobiles,
                        month: item
                    }
                }, function (err, response, body) {
                    if (!err && response.statusCode == 200) {
                        var body = JSON.parse(body);
                        if (body.code === 0) {
                            resolve(body.data);
                        } else {
                            resolve({})
                        }
                    } else {
                        resolve({});
                    }
                });
            });
        });

        var all = Promise.all(promises);

        var chargeInfoResult = yield all;

        var data = {};
        _.forEach(chargeInfoResult, function (monthInfo) {

            for (var key in monthInfo) {
                if (!data[key]) {
                    data[key] = [];
                }
                data[key].push(monthInfo[key]);
            }
        });

        var xlsData = [];
        for (var key in data) {
            var row = [];
            row.push(key);
            for (var i in data[key]) {
                var infos = data[key][i];
                for (var j in infos) {
                    var info = infos[j];
                    var msg = `${info.paymentMethod} | 金额 : ${info.paymentAmount}(分) | 时间 : ${info.payTime}`;
                    row.push(msg);
                }
            }
            xlsData.push(row);
        }

        var buffer = node_xlsx.build([{name: "sheet1", data: xlsData}]);
        res.attachment('充值查询结果.xlsx');
        res.send(buffer);
    });
});

router.post('/mobiles/add', upload.single('addMobiles'), function (req, res) {
    var file = req.file;

    var result = xlsxParser(file, parseMobiles);

    if (result.code !== 0) {
        res.json(httpResult.err_logic(result.msg));
        return;
    }

    co(function*() {
        var mobiles = result.data.mobiles.toString();
        var response = yield coRequest.post({
            url: 'http://service.lvyou189.cn:9001/mobiles/add',
            form: {
                mobiles: mobiles
            }
        });

        if (response.statusCode === 200) {
            var body = JSON.parse(response.body);
            if (body.code === 0) {
                res.json(httpResult.succ('ok'));
            } else {
                res.json(httpResult.err_logic(response.body));
            }
        } else {
            res.json(httpResult.err_logic(response.body));
        }
    });
});

router.post('/mobiles/init', upload.single('initMoblies'), function (req, res) {
    var open_time = req.body.openDate;
    if(!open_time){
        return res.json(httpResult.err_logic('没选择开卡日期'));
    }
    var file = req.file;

    var result = xlsxParser(file, parseCardInfo);
    if (result.code !== 0) {
        res.json(httpResult.err_logic(result.msg));
        return;
    }

    co(function*() {
        var allCards = yield dao.Card.find();
        var seq = allCards.length;
        var cards = result.data.cards;
        var respData = [];
        var newData = [];

        allCards = indexByKey(allCards, 'mobile');

        for (var i = 0; i < cards.length; i++) {
            var card = cards[i];
            var cardRecord = allCards[card.mobile];

            if (!cardRecord) {
                cardRecord = {
                    iccid : card.iccid,
                    mobile : card.mobile,
                    card_id : idGen.cardId(open_time, seq++),
                    card_pwd : idGen.cardPwd(),
                    open_time : new Date(open_time)
                };
                newData.push(cardRecord);
            }
            var respObj = {
                '序号' : i,
                '手机号' : cardRecord.mobile,
                'ICCID' : cardRecord.iccid,
                '卡号' : cardRecord.card_id,
                '密码' : cardRecord.card_pwd,
                '开卡时间' : moment(cardRecord.open_time).format('YYYY年MM月')
            };
            respData.push(respObj);
        }
        if(newData.length > 0){
            //保存mongo
            console.time('insert db');
            var insertResult = yield dao.Card.collection.insert(newData);
            console.timeEnd('insert db');
            yield coRequest.post({
                url: 'http://service.lvyou189.cn:9001/mobiles/add',
                form: {
                    mobiles: newData.map(function(item){return item.mobile}).join(',')
                }
            });
            console.log(`保存新卡共${insertResult.insertedCount}张`);
        }
        var resultData = buildCardResult(respData);

        res.attachment('卡号&密码.xlsx');
        res.send(resultData);

    }).catch(function (err) {
        console.log(err);
        res.json(httpResult.err_logic(err.message));
    });
});

/**
 * 获取订单信息by status, 不传则获取所有状态
 */
router.get('/orders', function (req, res){
    co(function*(){
        var status = req.query.status;
        var queryCondition = {};
        if(status){
            queryCondition.status = {$in : status.split(',')}
        }
        var orders = yield dao.Order.find(queryCondition);
        res.json(httpResult.succ(orders));
    }).catch(function(err){
        res.json(httpResult.err_logic(err));
    });
});

router.post('/orders/update', function(req, res){
    var orders = req.body.orders;
    co(function * (){
        if(!orders || orders.length === 0){
            throw '请求参数为空';
        }
        orders = JSON.parse(orders);
        var orderIds = orders.map(function(item){
            return item.orderId;
        });
        var condition = {
            order_id : {$in : orderIds},
            status : 2
        };
        var updateField = {
            status : 4,
            update_time : new Date()
        };
        var r = yield dao.Order.update(condition, updateField);
        console.log(r);
        res.json(httpResult.succ(r.nModified));
    }).catch(function(err){
        res.json(httpResult.err_logic(err));
    });
});

router.post('/orders/download', function(req, res){
    var orders = req.body.orders;
    if(!orders || orders.length === 0){
        res.json(httpResult.err_logic('请求参数为空'));
    }
    orders = JSON.parse(orders);

    var resultData = buildOrderResult(orders);

    res.attachment('付款成功账单.xlsx');
    res.send(resultData);
});

function buildOrderResult(body){
    var title = [
        {
            key : 'seq',
            name : '序号'
        },
        {
            key : 'orderId',
            name : '订单号'
        },
        {
            key : 'mobile',
            name : '充值号码'
        },
        {
            key : 'package',
            name : '流量包'
        },
        {
            key : 'amount',
            name : '充值金额(元)'
        },
        {
            key : 'time',
            name : '充值时间'
        }
    ];

    return buildResult(body, title);
}

function buildBatchResult(body) {
    var title = [
            {
                key : 'mobile',
                name : '号码'
            },
            {
                key : 'month',
                name : '月份'
            },
            {
                key : 'monthTrafficLeft',
                name : '月结余(KB)'
            },
            {
                key : 'totalTrafficLeft',
                name : '总结余(KB)'
            }
        ];

    return buildResult(body, title);
}

function buildCardResult(body){
    var title = [
        {
            key : '序号',
            name : '序号'
        },
        {
            key : '手机号',
            name : '手机号'
        },
        {
            key : 'ICCID',
            name : 'ICCID'
        },
        {
            key : '卡号',
            name : '卡号'
        },
        {
            key : '密码', name : '密码'
        },
        {
            key : '开卡时间', name : '开卡时间'
        }
    ];

    return buildResult(body, title);
}

function buildResult(body, titleArr){
    var
        data = [],
        title = titleArr.map(function(item){
            return item.name;
        });

    data.push(title);
    for (var key in body) {
        var row = [];
        _.each(titleArr, function(item){
            row.push(body[key][item.key]);
        });
        data.push(row);
    }

    var buffer = node_xlsx.build([{name: "sheet1", data: data}]);
    return buffer;
}

function xlsxParser(file, handler) {
    var result = {code: 1, msg: ''};

    if (!file.originalname.endsWith('xlsx') && !file.originalname.endsWith('xls')) {
        result.msg = '上传文件格式不正确，请上传excel文件';
        return result;
    }
    var arr = [];
    for (var i = 0; i != file.buffer.length; ++i) {
        arr[i] = String.fromCharCode(file.buffer[i]);
    }
    var bstr = arr.join('');

    var wb = XLSX.read(bstr, {type: 'binary'});

    var first_sheet_name = wb.SheetNames[0];

    /* Get worksheet */
    var ws = wb.Sheets[first_sheet_name];
    return handler(ws);
}

function parseMobiles(ws) {
    //code = 1,有错误; code = 0, 正确解析,内容在data
    var result = {
        code: 1,
        msg: '',
        data: {}
    };
    var mobiles = [];
    for (var m in ws) {
        /* all keys that do not begin with "!" correspond to cell addresses */
        if (m[0] === '!') continue;
        mobiles.push(ws[m].w);
    }

    if (result.msg.length == 0) {
        result.code = 0;
        result.data.mobiles = mobiles;
    }
    return result;
}

function parseCardInfo(ws) {
    //code = 1,有错误; code = 0, 正确解析,内容在data
    var result = {
        code: 1,
        msg: '',
        data: {}
    };

    var cards = [];
    var jsonView = XLSX.utils.sheet_to_json(ws);

    _.each(jsonView, function (item) {
        cards.push({
            iccid: item['ICCID'],
            mobile: item['手机号']
        });
    });

    if (result.msg.length == 0) {
        result.data.cards = cards;
        result.code = 0;
    }
    return result;
}

module.exports = router;
